//===============================================================================
// Microsoft patterns & practices Enterprise Library Contribution
// Logging Application Block
//===============================================================================
// License: http://www.codeplex.com/entlibcontrib/Project/License.aspx
// Author: Randy
//===============================================================================

using System;
using System.Diagnostics;
using System.IO;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;

namespace EntLibContrib.Logging.TraceListeners
{
	/// <summary>
	/// A <see cref="TraceListener"/> that writes to a flat file, formatting the output with an <see cref="ILogFormatter"/>.
	/// </summary>
	[ConfigurationElementType(typeof(FlatFileTraceListenerData))]
	public class NoGuidFlatFileTraceListener : NoGuidFormattedTextWriterTraceListener
	{
		#region Fields
		string header = String.Empty;
		string footer = String.Empty;
		#endregion

		#region Construction
		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/>.
		/// </summary>
		public NoGuidFlatFileTraceListener()
			: base()
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(ILogFormatter formatter)
			: base(formatter)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="FileStream"/> and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="stream">The file stream writen to.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(FileStream stream, ILogFormatter formatter)
			: base(stream, formatter)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="FileStream"/>.
		/// </summary>
		/// <param name="stream">The file stream.</param>
		public NoGuidFlatFileTraceListener(FileStream stream)
			: base(stream)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="StreamWriter"/> and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="writer">The stream writer.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(StreamWriter writer, ILogFormatter formatter)
			: base(writer, formatter)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="StreamWriter"/>.
		/// </summary>
		/// <param name="writer">The stream writer.</param>
		public NoGuidFlatFileTraceListener(StreamWriter writer)
			: base(writer)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a file name and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="fileName">The file name.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(string fileName, ILogFormatter formatter)
			: base(fileName, formatter)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a file name.
		/// </summary>
		/// <param name="fileName">The file name.</param>
		public NoGuidFlatFileTraceListener(string fileName)
			: base(fileName)
		{
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a file name, a header, a footer and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="fileName">The file stream.</param>
		/// <param name="header">The header.</param>
		/// <param name="footer">The footer.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(string fileName, string header, string footer, ILogFormatter formatter)
			: base(fileName, formatter)
		{
			this.header = header;
			this.footer = footer;
		}

		/// <summary>
		/// Initializes a new instance of <see cref="NoGuidFlatFileTraceListener"/> with a file name, a header, and a footer.
		/// </summary>
		/// <param name="fileName">The file stream.</param>
		/// <param name="header">The header.</param>
		/// <param name="footer">The footer.</param>
		public NoGuidFlatFileTraceListener(string fileName, string header, string footer)
			: base(fileName)
		{
			this.header = header;
			this.footer = footer;
		}

		/// <summary>
		/// Initializes a new named instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="FileStream"/> and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="stream">The file stream.</param>
		/// <param name="name">The name.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(FileStream stream, string name, ILogFormatter formatter)
			: base(stream, name, formatter)
		{
		}

		/// <summary>
		/// Initializes a new name instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="FileStream"/>.
		/// </summary>
		/// <param name="stream">The file stream.</param>
		/// <param name="name">The name.</param>
		public NoGuidFlatFileTraceListener(FileStream stream, string name)
			: base(stream, name)
		{
		}

		/// <summary>
		/// Initializes a new named instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="StreamWriter"/> and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="writer">The stream writer.</param>
		/// <param name="name">The name.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(StreamWriter writer, string name, ILogFormatter formatter)
			: base(writer, name, formatter)
		{
		}

		/// <summary>
		/// Initializes a new named instance of <see cref="NoGuidFlatFileTraceListener"/> with a <see cref="StreamWriter"/>.
		/// </summary>
		/// <param name="writer">The stream writer.</param>
		/// <param name="name">The name.</param>
		public NoGuidFlatFileTraceListener(StreamWriter writer, string name)
			: base(writer, name)
		{
		}

		/// <summary>
		/// Initializes a new named instance of <see cref="NoGuidFlatFileTraceListener"/> with a file name and
		/// a <see cref="ILogFormatter"/>.
		/// </summary>
		/// <param name="fileName">The file name.</param>
		/// <param name="name">The name.</param>
		/// <param name="formatter">The formatter.</param>
		public NoGuidFlatFileTraceListener(string fileName, string name, ILogFormatter formatter)
			: base(fileName, name, formatter)
		{
		}

		/// <summary>
		/// Initializes a new named instance of <see cref="NoGuidFlatFileTraceListener"/> with a file name.
		/// </summary>
		/// <param name="fileName">The file name.</param>
		/// <param name="name">The name.</param>
		public NoGuidFlatFileTraceListener(string fileName, string name)
			: base(fileName, name)
		{
		}
		#endregion

		#region Public Methods
		/// <summary>
		/// Delivers the trace data to the underlying file.
		/// </summary>
		/// <param name="eventCache">The context information provided by <see cref="System.Diagnostics"/>.</param>
		/// <param name="source">The name of the trace source that delivered the trace data.</param>
		/// <param name="eventType">The type of event.</param>
		/// <param name="id">The id of the event.</param>
		/// <param name="data">The data to trace.</param>
		/// <remarks>
		/// Formatting is only performed if the object to trace is a <see cref="LogEntry"/> and the formatter is set.
		/// </remarks>
		public override void TraceData(TraceEventCache eventCache, string source, TraceEventType eventType, int id, object data)
		{
			if (header.Length > 0)
				WriteLine(header);

			LogEntry logEntry = data as LogEntry;
			if (logEntry != null)
			{
				if (this.Formatter != null)
				{
					base.WriteLine(this.Formatter.Format(logEntry));
				}
				else
				{
					base.TraceData(eventCache, source, eventType, id, data);
				}
				InstrumentationProvider.FireTraceListenerEntryWrittenEvent();
			}
			else
			{
				base.TraceData(eventCache, source, eventType, id, data);
			}

			if (footer.Length > 0)
				WriteLine(footer);
		}
		#endregion

		#region Protected Methods
		/// <summary>
		/// Declare the supported attributes for <see cref="NoGuidFlatFileTraceListener"/>
		/// </summary>
		/// <returns>
		/// A string array naming the custom attributes supported by the trace listener, or null if there are no custom attributes.
		/// </returns>
		protected override string[] GetSupportedAttributes()
		{
			return new string[4] { "formatter", "fileName", "header", "footer" };
		}
		#endregion
	}
}
